<?php

namespace App\Service;

use App\Entity\Money;
use App\Entity\MoneyLogType;
use App\Entity\MoneyPayOrder;
use App\Entity\MoneyType;
use App\Entity\Orders;
use App\Entity\User;
use App\Repository\ConfigRepository;
use App\Repository\MoneyLogRepository;
use App\Repository\MoneyLogTypeRepository;
use App\Repository\MoneyPayOrderRepository;
use App\Repository\MoneyRepository;
use App\Repository\MoneyStaticRepository;
use App\Repository\MoneyTypeRepository;
use App\Repository\UserRepository;
use App\Service\Wechat\WechatPay;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
use Symfony\Component\HttpFoundation\Request;

class PayService extends DocumentRepository
{
    //支付参数设置
    const __PAY_TYPE_WECHAT__ = 100;
    const __PAY_TYPE_ALIPAY__ = 200;
    const __PAY_TYPE_UNION__ = 300;


    public $shopService;
    public $moneyService;
    public $orderService;
    public $taskService;
    public $userRepository;
    public $moneyRepository;
    public $moneyLogRepository;
    public $moneyTypeRepository;
    public $moneyStaticRepository;
    public $moneyLogTypeRepository;
    public $moneyPayOrderRepository;
    public $configRepository;

    public function __construct(
        DocumentManager $dm
        , MoneyService $moneyService
        , OrderService $orderService
        , UserRepository $userRepository
        , MoneyRepository $moneyRepository
        , MoneyLogRepository $moneyLogRepository
        , MoneyTypeRepository $moneyTypeRepository
        , MoneyStaticRepository $moneyStaticRepository
        , MoneyLogTypeRepository $moneyLogTypeRepository
        , MoneyPayOrderRepository $moneyPayOrderRepository
        , ConfigRepository $configRepository
    )
    {
//        parent::__construct($registry, Money::class);
        parent::__construct($dm, $dm->getUnitOfWork(), $dm->getClassMetadata(Money::class));

        $this->moneyService = $moneyService;
        $this->orderService = $orderService;
        $this->userRepository = $userRepository;
        $this->moneyRepository = $moneyRepository;
        $this->moneyLogRepository = $moneyLogRepository;
        $this->moneyTypeRepository = $moneyTypeRepository;
        $this->moneyStaticRepository = $moneyStaticRepository;
        $this->moneyLogTypeRepository = $moneyLogTypeRepository;
        $this->moneyPayOrderRepository = $moneyPayOrderRepository;
        $this->configRepository = $configRepository;
    }

    /**
     * @param User $user
     * @param float $money
     * @param null $param
     * @param MoneyLogType|null $logType
     * @param MoneyType|null $moneyType
     * @return MoneyPayOrder
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function createPayOrder(User $user, float $money, MoneyType $moneyType = null, $param = null, MoneyLogType $logType = null)
    {
        $order = new MoneyPayOrder();
        $order->setUser($user)
            ->setMoney($money)
            ->setCreateAt(new \DateTime())
            ->setPayAt(null)
            ->setSn(uniqid($user->getId()))//回调唯一码
            ->setData(null)//回调数据
            ->setLogType($logType)
            ->setMoneyType($moneyType)
            ->setParam($param);
        $this->dm->persist($order);
        $this->dm->flush();
        return $order;
    }


    //---------------支付参数拉去
    public function createPayParam($money, $payType, $cbCode, $cbStr = "", $openId = "")
    {//小程序 和 网页支付
        switch ($payType) {
            case 100://微信支付
                $wechatPay = new WechatPay();
                if (!$openId) {
                    return false;
                }
                return $wechatPay->createOrder($openId, "订单支付", $cbCode, $money, $cbStr);
            case 200://支付宝支付
                $alipay = new Alipay\Alipay();
                return $alipay->createOrder($cbCode, $money, 0, "订单支付", $cbStr);
            case 500://余额支付
            default:
                return false;
        }

    }

    public function createAppPayParam($money, $payType, $cbCode, $cbStr = "")
    {//app支付
        switch ($payType) {
            case 100://微信支付
                $wechatPay = new WechatPay();
                return $wechatPay->createAppOrder("订单支付", $cbCode, $money, $cbStr);
            case 200://支付宝支付
                $alipay = new Alipay\Alipay();
                return $alipay->createOrder($cbCode, $money, 0, "订单支付", $cbStr);
            case 500://余额支付
            default:
                return false;
        }

    }

    //------在线支付相关：创建回调订单，回调处理----end
    public function dealWithCallBackUserCharge($sn)
    {
        $payOrder = $this->moneyPayOrderRepository->findOneBy(array("sn" => $sn));
        if ($payOrder->getPayAt()) {
            return false;//已经处理过了
        }
        $request = Request::createFromGlobals();
        $data = [
            "get" => $_GET
            , "post" => $_POST
            , "input" => "php://input"
            , "req_request" => $request->request->all()
            , "req_query" => $request->query->all()
            , "request" => $request
        ];
        //修改订单支付信息
        $payOrder->setPayAt(new \DateTime())->setData($data);
        $this->dm->persist($payOrder);
        $this->dm->flush();
        //修改订单支付信息
        $this->moneyService->mod($payOrder->getUser(), $payOrder->getMoney(), MoneyService::__MONEY_XIAN_JIN__, "101", "在线充值");
        //添加充值赠款
        $charge = $this->configRepository->getKVNumArray("CHARGE");
//        $moneys = array_keys($charge);
        $array = [];
        foreach ($charge as $row) {
            $array[] = $row[0];
            if ($payOrder->getMoney() == $row[0]) {
                $bonus = $row[1];
                $this->moneyService->mod($payOrder->getUser(), $bonus, MoneyService::__MONEY_XIAN_JIN__, "101", "充值赠送");
            }
        }
    }

    public function dealWithCallBackOrder($sn)
    {
        $payOrder = $this->moneyPayOrderRepository->findOneBy(array("sn" => $sn));
//        dump($payOrder);
        if ($payOrder->getPayAt()) {
            return false;//已经处理过了
        }
        $request = Request::createFromGlobals();
        $data = [
            "get" => $_GET
            , "post" => $_POST
            , "input" => "php://input"
            , "req_request" => $request->request->all()
            , "req_query" => $request->query->all()
            , "request" => $request
        ];

        $payOrder->setPayAt(new \DateTime())->setData($data);
        $this->dm->persist($payOrder);
        $this->dm->flush();
        $param = $payOrder->getParam();
        $orderId = $param["orderId"];

        $rst = $this->orderService->dealWithOrderPay($orderId);
    }


    public function uniCallBack($sn, $from = "")
    {
        switch ($from) {
            case "order":
                $this->dealWithCallBackOrder($sn);
                break;
            case "charge":
                $this->dealWithCallBackUserCharge($sn);
                break;
        }
    }

    public function refund($sn)
    {
        /**@var  $order Orders */
        $order = $this->orderService->findOneBy(array("sn"=>$sn));
        $payOrder = $this->moneyPayOrderRepository->findOneBy(array("param.orderId"=>$order->getId()));
        $out_trade_no = $payOrder->getSn();
//        dump([$order,$payOrder]);
        $refund = "";
        switch ($order->getPayType()) {
            case 100:
                $wechatPay = new WechatPay();
                $money = $order->getPayReal();
//                $money = 0.02;//todo 上线修改
                $refund = $wechatPay->createRefund($out_trade_no,$money);
                break;
            case 500://余额支付
                $this->moneyService->mod($order->getUser(),$order->getPayReal(),MoneyService::__MONEY_XIAN_JIN__,"101","订单退款");
        }
        $order->setStatus(3);
        $this->dm->persist($order);
        $this->dm->flush();

        return [$order,$payOrder,$refund];

    }
}